﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using System.Reflection;
using System.Web;

namespace XSTDZ.ERP.Infrastructure
{
    /// <summary>
    /// 服务加载器(对象管理器）
    /// </summary>
    public class ServiceLocator : IServiceProvider
    {
        private  readonly IUnityContainer _unityContainer;
        private static readonly ServiceLocator _serviceLocator = new ServiceLocator();

        public ServiceLocator()
        {
            if (this._unityContainer == null)
            {
                 var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                _unityContainer = new UnityContainer();
                section.Configure(_unityContainer);

            }

        }
        /// <summary>
        /// 服务加载器实例对象
        /// </summary>
        public static ServiceLocator Instance
        {
            get { return _serviceLocator; }
        }
        /// <summary>
        /// 对象容器对象
        /// </summary>
        public  IUnityContainer ObjectContainer
        {
            get { return _unityContainer; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetService<T>()
        {
            return ObjectContainer.Resolve<T>();
        }
        public T GetService<T>(object parameters)
        {
            var paras = GetParameterOverrides(parameters);
            return ObjectContainer.Resolve<T>(paras.ToArray());
        }
        public object GetService(Type serviceType, object parameters)
        {
            var paras = GetParameterOverrides(parameters);
            return _unityContainer.Resolve(serviceType, paras.ToArray());
        }
        public object GetService(Type serviceType)
        {
            return _unityContainer.Resolve(serviceType);
        }

        private IEnumerable<ParameterOverride> GetParameterOverrides(object overrideParameter)
        {
            var paras = new List<ParameterOverride>(0);
            Type parasType = overrideParameter.GetType();
            parasType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .ToList()
                .ForEach(propertyInfo => {
                    var propertyValue = propertyInfo.GetValue(overrideParameter, null);
                    var propertyName = propertyInfo.Name;
                    paras.Add(new ParameterOverride(propertyName, propertyValue));
                });
            return paras;
        }
    }
}
